那隻草泥馬因為頭痛的關係,讓牠常常晚上睡不好覺。事實上,牠幾乎什麼狀況都有:牙痛、面皰、近視、散光、氣喘、扁平足。你多多少少會為牠感到難過的,那隻可憐的草泥馬。
~節錄自《賴田捕手》第五章
今天我們要繼續講一些Python所提供的兩種資料型態:清單(list)跟不可變更的清單(tuple),以及相關的操作。這兩種資料型態跟昨天相比,屬於更複雜的,具有結構的資料型態。昨天講到的布林(boolean)、整數(integer)、浮點數(float)、字串(string),是 Python 中最基礎的幾樣資料型態,這些資料型態就像是磚塊,可以一塊一塊有系統、有組織的堆疊起來,變成清單。今天我們要用這些磚塊來起高樓,宴賓客了!
大家出門逛街的時候,是否會有個習慣,先準備好一份購物清單,方便在商店裡繞得暈頭轉向的時候,低頭看看,還能夠記得這次出門需要購買的東西。或是帶著可憐的草泥馬去醫院就診之前,準備好一份病歷表,方便在醫院裡繞得暈頭轉向的時候,低頭看看,還能夠記得這次出門需要掛號的科別。大家會怎麼弄出一份方便好懂得清單呢?不外乎是['toothache', 'pimple', 'myopia', 'astigmatism', 'asthma', 'flatfloot']
吧?其實在Python裡面,創造一份清單(list)類型的物件,也是用相同的做法喔!
In [1]: medical_list = ['toothache', 'pimple', 'myopia', 'astigmatism', 'asthma', 'flatfloot']
type(medical_list)
Out[1]: list
另外,也可以透過將其他類型的物件清單化的方式,來創造出新的清單物件。方法想必大家都不陌生,就是用list()
。不過,可以數(ˇ)數(ˋ)的物件才能做成清單,因此丟進list()
的物件,必須要可以數(ˇ)數(ˋ)。大家還記得我們學過哪些可以數(ˇ)數(ˋ)的物件嗎?
In [2]: list('123')
Out[2]: ['1', '2', '3']
如果不是可以數(ˇ)數(ˋ)的物件:
In [3]: list(123)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-1c325c17b3d1> in <module>
----> 1 list(123)
TypeError: 'int' object is not iterable
有了清單之後,想要查看清單中項目的數量,可以像字串一樣,用len()
。如果我們想知道清單中位置在第 x 的項目,怎麼做呢?想必大家都很清楚了。如果想知道清單中,從位置在第 x 的項目開始,到位置在第 y 的項目為止,每隔 z 個項目取一個,該怎麼做呢?想必大家也都很清楚了,就代公式嘛![開始的x:結束的y:間隔的z]
In [4]: print('Length of list\t:', len(medical_list))
print('[0]\t\t:', medical_list[0])
print('[1:5:3]\t\t:', medical_list[1:5:3])
Length of list : 6
[0] : toothache
[1:5:3] : ['pimple', 'asthma']
當我拿右手著這份病歷表,左手牽著草泥馬艾克莉在醫院裡翹首四顧之時,我的合作夥伴拿著另一份清單來找我,說他一直忘了告訴我,其實可憐的艾克莉身體最近又出了一些小狀況。
「頭暈,噁心,想吐」他無奈的拍拍艾克莉的頭,要我試著找醫生也幫忙看看這些毛病。好吧,看來我得增加一些項目到我的清單上了。怎麼做呢?我們有三種方式:
append()
把項目一個一個放到清單中In [5]: medical_list = ['toothache', 'pimple', 'myopia', 'astigmatism', 'asthma', 'flatfloot']
medical_list.append('headache')
medical_list.append('nausea')
medical_list.append('vomitting')
medical_list
Out[5]: ['toothache',
'pimple',
'myopia',
'astigmatism',
'asthma',
'flatfloot',
'headache',
'nausea',
'vomitting']
extend()
把兩個清單合併在一起In [6]: medical_list = ['toothache', 'pimple', 'myopia', 'astigmatism', 'asthma', 'flatfloot']
recent_illness = ['headache', 'nausea', 'vomitting']
medical_list.extend(recent_illness)
medical_list
Out[6]: ['toothache',
'pimple',
'myopia',
'astigmatism',
'asthma',
'flatfloot',
'headache',
'nausea',
'vomitting']
+
把兩個清單加在一起In [7]: medical_list = ['toothache', 'pimple', 'myopia', 'astigmatism', 'asthma', 'flatfloot']
recent_illness = ['headache', 'nausea', 'vomitting']
medical_list = medical_list + recent_illness
medical_list
Out[7]: ['toothache',
'pimple',
'myopia',
'astigmatism',
'asthma',
'flatfloot',
'headache',
'nausea',
'vomitting']
大家稍微注意一下上面第 3 行程式碼:medical_list = medical_list + recent_illness
。事實上,在程式裡面,會常常用到這種操作,也就是我的錢 = 我的錢 + 你的錢
。Python為了讓大家打字方便一點,允許把這種敘述簡化為我的錢 += 你的錢
。任何運算符號都可以用這種操作。因此上面的程式碼又可以寫成:
In [8]: medical_list = ['toothache', 'pimple', 'myopia', 'astigmatism', 'asthma', 'flatfloot']
recent_illness = ['headache', 'nausea', 'vomitting']
medical_list += recent_illness # 我改了這行
medical_list
Out[8]: ['toothache',
'pimple',
'myopia',
'astigmatism',
'asthma',
'flatfloot',
'headache',
'nausea',
'vomitting']
更多的例子:
In [9]: 底數 = 2
對數 = 10
底數 **= 對數
底數 # 已經不是底數的底數
Out[9]: 1024
上面那段程式碼,我又偷偷加了一些新東西:井字號(#
)。井字號是用來記錄註解的方法。井字號後面的東西,不會被當成程式碼,所以不會影響程式的運作。
我看著手上又增加了3個項目的看診清單,心中不禁暗暗咒罵,我的合作夥伴居然犯了一個低級錯誤:他拼錯字了。'vomiting'
而不是'vomitting'
。看仔細了,中間只有一個t。好吧,看來得稍微改一下這個清單了。怎麼做呢?其實很簡單,就把清單中原本代表'vomitting'
這個錯字的位置,重新指定給正確的'vomiting'
就行了。我用眼睛看知道'vomitting'
在清單中的位置,Python用index()
知道'vomitting'
在清單中的位置。
In [10]: medical_list = ['toothache', 'pimple', 'myopia', 'astigmatism', 'asthma', 'flatfloot', 'headache', 'nausea', 'vomitting']
print('vomitting 的位置:', medical_list.index('vomitting'))
medical_list[(medical_list.index('vomitting'))] = 'vomiting'
print('拼字正確的清單', medical_list)
vomitting 的位置: 8
拼字正確的清單 ['toothache', 'pimple', 'myopia', 'astigmatism', 'asthma', 'flatfloot', 'headache', 'nausea', 'vomiting']
這邊我故意把程式碼寫得繞口一點,大家可以慢慢看,訓練一下對程式碼的理解能力。
好不容易,我把看診清單更新過了,馬不停蹄的掛了號,坐在醫院的休息區,忐忑不安地等候看診。終於有一個門診叫號叫到艾克莉了,是要幫忙看'pimple'
的醫生。進去診間,醫生向我詢問了艾克莉的狀況,煞有介事的點點頭,用瞳孔筆對著艾克莉的眼睛照了照,低頭寫了幾行字,開了個藥方,告訴我只要讓艾克莉早睡早起,調整生活習慣,很快就不會有問題了。我鬆了一口氣,低頭看了看手上的看診清單,想把'pimple'
從清單中劃掉,留下還需要等候看診的。該怎麼做呢?
首先,介紹一個比較麻煩的方法,pop()
。pop()
會將清單中最後一個項目1. 拿出來、2. 給你看。舉個例子來看:
In [11]: medical_list = ['toothache', 'pimple', 'myopia', 'astigmatism', 'asthma', 'flatfloot', 'headache', 'nausea', 'vomiting']
print('2. 給你看', medical_list.pop())
print('1. 拿出來', medical_list)
2. 給你看 vomiting
1. 拿出來 ['toothache', 'pimple', 'myopia', 'astigmatism', 'asthma', 'flatfloot', 'headache', 'nausea']
因為已經拿出來給你看了,所以我們的清單就少了'vomiting'
這個項目了。等等,我要拿出來的不是'vomiting'
吧?
pop()
在沒有預設變數的情況下,會默認你要輸入的程式碼是pop(-1)
,認為你有興趣的是最後一個項目,因此把最後一個項目拿出來給你看。那要怎麼拿出'pimple'
而不是'vomiting'
呢?很簡單,在pop()
中輸入'pimple'
的位置就行啦。再一次,我用眼睛看知道'pimple'
的位置。Python用index()
看知道'pimple'
的位置。
In [12]: medical_list = ['toothache', 'pimple', 'myopia', 'astigmatism', 'asthma', 'flatfloot', 'headache', 'nausea', 'vomiting']
print('pimple的位置', medical_list.index('pimple'))
print('拿出來給你看', medical_list.pop(medical_list.index('pimple')))
print(medical_list)
pimple的位置 1
拿出來給你看 pimple
['toothache', 'myopia', 'astigmatism', 'asthma', 'flatfloot', 'headache', 'nausea', 'vomiting']
太好了,醫生說艾克莉的'pimple'
問題不是太嚴重呢!
殘酷的現實:其實清單還有更多的操作可以玩,我就先把這些放到表一去了,有興趣的可以自己再研究研究!
表一、常用的清單(list)操作方式➀
語法 | 效果 |
---|---|
list.extend()或 += | 合併list |
list.insert() | 在指定位置插入元素,如果位置超過最大長度則放在最後面,故不會飛到很遠去或出錯。 |
del Object | 用來刪除某個位置的元素,剩餘元素會自動往前補填補 |
list.remove() | 用來移除指定元素 |
list.pop() | 為類似剪出的效果,可以將指定位置的元素剪出來,預設index為 -1 |
list.index() | 找查指定元素第一次出現的index |
in Object | 判斷指定元素是否存在 |
list.count() | 計算指定元素出現次數 |
Python提供另外一種不能變更的清單,叫做tuple。要創造tuple很簡單,把項目一個一個列出來,中間用逗號(,
)隔開就成了一個tuple。為了閱讀方便,習慣上也可以在前後用()
將所有項目包在一起。
In [13]: medical_tuple = ('toothache', 'pimple', 'myopia', 'astigmatism', 'asthma', 'flatfloot', 'headache', 'nausea', 'vomitting')
type(medical_tuple)
Out[13]: tuple
舉一反三,我們也可以用tuple()
從可以數數的物件中創造出不可變更的清單:
In [14]: medical_list = ['toothache', 'pimple', 'myopia', 'astigmatism', 'asthma', 'flatfloot', 'headache', 'nausea', 'vomitting']
medical_tuple = tuple(medical_list)
medical_tuple
('toothache',
'pimple',
'myopia',
'astigmatism',
'asthma',
'flatfloot',
'headache',
'nausea',
'vomitting')
我們一樣可以用[x]
選擇位置在第 x 的項目,一樣可以用[x:y:z]
去對tuple做取樣的動作,但是這次我們就沒辦法更改裡面的項目了。
In [15]: medical_tuple[-1]
Out[15]: 'vomitting'
咦?vomitting?
In [16]: medical_tuple[-1] = 'vomiting'
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-14-76f9e11e8084> in <module>
----> 1 medical_tuple[-1] = 'vomiting'
TypeError: 'tuple' object does not support item assignment
慘了拼錯字了。
今天關於Python的物件類型就先介紹到這裡,明天會繼續來介紹更多精彩的物件類型。一樣,今天文章中的程式碼範例都有放在 Github 上(Github 或 nbviewer),有興趣的或我沒講清楚的,可以試著下載下來玩玩看!謝謝大家!
➀ Introducing Python、Introducing Python 閱讀筆記第三章
註:對於此系列文有興趣的讀者,歡迎參考由此系列文擴編成書的 LINE Bot by Python,以及最新的系列文《賴田捕手:追加篇》
第 31 天 初始化 LINE BOT on Heroku
第 32 天 快速回覆 QuickReply 介紹
第 33 天 妥善運用 Heroku APP 暫存空間
第 34 天 妥善運用 LINE Notify 免費推播
第 35 天 製造 Deploy to Heroku 按鈕
辛勤的草泥馬們,晚上好~
又到了工作之餘的學習時間,感覺自己就像個問題學生...
也請作者多多包涵>"<a 真的找不到身邊的親朋好友解答我的疑惑...
進入正題XD,每一篇對我來說都是珍寶,除了複製貼上之外,自己也很希望能親自參與,所以我寫了很小一段程式碼..但不懂它的回覆為何如此?
學習過程中,我明白[起始:結束]是從起始開始但不包含結束,而[::]是從一而終的用法,但應也不包含結束。
得到這結果,讓我思考兩天...........
還請草泥馬們,幫幫忙解惑>Q<a
還是我對[]的理解還是有問題的0.0?
您好:
比較讓您感到疑惑的,應該是
print('水果_list:', fruit[fruit.index('apple'):fruit.index('strawberry'):3])
print('水果_list_1:', fruit[::3])
這兩個切片的差別吧?
沒問題,讓我們再來一遍:
In [1]: 排好的數字 = "0123456789"
開始 = 0
結束 = 10
間隔 = 3
print("A.", 排好的數字[開始:結束:間隔])
Out[1]: A. 0369
因為 python 總是從零開始,所以當我們的切片開始為0
的時候,可以不特別指定:
In [2]: 排好的數字 = "0123456789"
結束 = 10
間隔 = 3
print("B.", 排好的數字[:結束:間隔])
Out[2]: B. 0369
當我們不特別指定結束的時候,得到的結果如下:
In [3]: 排好的數字 = "0123456789"
間隔 = 3
print("C.", 排好的數字[::間隔])
Out[3]: C. 0369
意思是,當我們不特別指定結束的時候,python 會認為我們想要的結束是10
。而不是9
。為什麼是10
呢?這個數字哪裡來的呢?
In [4]: 排好的數字 = "0123456789"
結束 = len(排好的數字)
間隔 = 3
print("D.", 排好的數字[:結束:間隔])
Out[4]: D. 0369
若用的是9
,還記得 python 切片的原則,包含開始的 (此例為0
),不包含結束的 (此例為9
):
In [5]: 排好的數字 = '0123456789'
結束 = 排好的數字.index('9')
間隔 = 3
print("E.", 排好的數字[:結束:間隔])
Out[5]: E. 036
所以,當我們什麼都不指定的時候,python 會認為我們的切片要切到最後 (len(排好的數字)
),而不是只到9
而已喔。
另外,最近也看到心原一馬大大關於切片的教學文,覺得挺不錯的,也供您參考看看囉!